/*
 * Funambol is a mobile platform developed by Funambol, Inc. 
 * Copyright (C) 2008 Funambol, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission 
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License 
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 * 
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably 
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#ifndef INCL_RECURRENCE_DATASTORE
#define INCL_RECURRENCE_DATASTORE

#include "SQLiteDriver.h"
#include "Date.h"
#include "Event.h"
#include "Recurrence.h"

using namespace Funambol;

class RecurrenceDataStore {

private:
    /**
    * The SQLiteDriver to store in the database. It is the same istance of the driver that is in the
    * event data store. The RecurrenceEventDataStore doesn't exists if no event exists
    */
    SQLiteDriver& driver;
      
    /**
    * Creates the query to insert the recurrence in the storage
    */    
    StringBuffer createInsertRecurrenceStmt(const char* id_event, Recurrence& rec);
    StringBuffer createInsertRecurrenceChangesStmt(const char* rec_id, const char* event_id, Event& event);
    StringBuffer createInsertOccurrenceCacheStmt(const char* event_id, 
                                        const char* day, 
                                        const char* occurrenceDate, 
                                        Event& event);
    /**
    * Creates the query to delete the item from the storage
    */    
    StringBuffer createDeleteRecurrenceStmt(const char* id);
    StringBuffer createDeleteRecurrenceChangesStmt(const char* rec_id, 
                                                   const char* event_id, 
                                                   const char* calendar_id);
    
    /**
    * Creates the query to update an recurrence in the storage
    */    
    StringBuffer createUpdateRecurrenceStmt(const char* identifier, Event& event);
        
    /**
    * It populates an Recurrence object from an arrayList with all the fields populated from the
    * db.
    * @param al the arraylist containing all the fields
    * @return the Recurrence object filled with the data. It should be added to the 
    *         Event object. If there is any error, the returned value is NULL
    */
    Recurrence* populateRecurrence(const ArrayList& al);
    
    /**
     * It check in the recurrence table if there is an recurrence for the
     * current event (identifier). If any exists, the ids (tipically one) are
     * are stored in the al array list
     */
    bool containsRecurrence(const char* identifier, ArrayList& al);
    
    /**
     * It fills the arraylist with the years to calculate the occurrences.
     * It is used when for the no end date recurring appointment. These years
     * need to calculate the timezone record in the TZ field
     */
    void fillRecurringNoEndDateYears(long date, ArrayList& list);
    
    /**
     * It calculates the occurrences of the recurring event given a Recurrence
     * Objcet (to get the type and other info) and the start date of it.
     * Used to get the occurrences existing in the database to format
     * an existing event
     */
    int getExistingOccurrences(Recurrence& recurrence, Date& start);
    
    /**
     * It fills all the occurrences in the day and the occurrence_date that must be filled
     * for the list view of the appointment.
     * Used to determinate how many occurrences there are for event that comes from server.
     * It calculates also the lastest recurrence day that must be at 23.59.59 in GMT +00 of the latest day.
     * This value is set in the recurrence end date
     * @todo: investigate on how many appointments occurrences have to be filled for every
     * appointment event. It is not so clear at the moment. Suppose something that has to be improved
     */
    int calculateOccurrencesDates(Event& event);
    
public:
    
    RecurrenceDataStore(SQLiteDriver& d) : driver(d) { }
        
    ~RecurrenceDataStore() {}

    /**
    * The method inserts a Recurrence using the id of the event. It is no needed
    * to have the id of the Recurrence just inserted.
    */
    int insertRecurrence(Event& item, const char* id_event);

    int updateRecurrence(Event& item, const char* id_event);

    int deleteRecurrence(const char* id_event);

    Recurrence* getRecurrence(Event& event, const char* id_event);
        
};
#endif
